/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Mutli;

import java.awt.image.SampleModel;
import java.util.concurrent.Semaphore;
import java.util.logging.Level;
import java.util.logging.Logger;
import mediana.Bufor;
import mediana.Range;
import mediana.Table;

/**
 *
 * @author mateusz.ledzewicz
 */
public class SortThread extends Thread{
    public static boolean autoCreateThread = false; 
    private Semaphore sem;
    private Table table;
    
    public SortThread(Semaphore sem, Table table){
        super();
        this.sem= sem;
        this.table= table;   
    }
     
       
    @Override
    public void run(){
        try {
            
            while(true){
            sem.acquire();
           
            this.log("Start" + sem.availablePermits());
            Range range = Bufor.popRange();
            if(range == null) break;
            int pivot = (range.getMax() + range.getMin())/2;
            int pivotValue = this.table.getElement(pivot);
            this.table.swap(pivot, range.getMax());
            int j = range.getMin();
            
            for(int i=range.getMin(); i<=range.getMax()-1;i++){
                if(this.table.getElement(i) >= pivotValue) continue;
                this.table.swap(i, j);
                j++;
            }
            this.table.swap(range.getMax(), j);
            
            //System.out.println(this.table);
            this.log("End sorting");
            if(j+1 < range.getMax()){
                Bufor.pushRange(new Range(j+1, range.getMax()));
                 if(autoCreateThread)
                    new SortThread(sem, table).start();
                //sem.release();
                
            }
            if(j-1 > range.getMin()){
                Bufor.pushRange(new Range(range.getMin(), j-1));
                if(autoCreateThread)
                    new SortThread(sem, table).start();
                //sem.release();
                
            }
            if(sem.availablePermits() < mediana.Mediana.BeginThreadNumber)
                sem.release(1);
            }
            sem.release();
            
            

            
            
        } catch (InterruptedException ex) {
            Logger.getLogger(SortThread.class.getName()).log(Level.SEVERE, null, ex);
        } 
        
        
        
    }
    
   
    
    private void log(String message){
        //System.out.println(this.getName() + ": " + message );
    }
}
